/**  
 * Copyright (c) 2010 University of Pennsylvania.
 *     All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an "AS
 *  IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 *  express or implied.  See the License for the specific language
 *  governing permissions and limitations under the License.
 *
 */
 
#define MAX_PATHCOLLAPSEHINTS         2   // number of path collapse hints to be merged into 1 msg

#ifdef MINIMUM_MEMORY
  #define MAX_MERGETUPLECOUNT         2   // max merged data values per message
#else
  #define MAX_MERGETUPLECOUNT         4
#endif

#define MAX_STATLOGFILESIZE          2000                      // maximum size of text to write to log buffer
#define MAX_STATSIZE                 (MAX_FORWARDDATASIZE-10)  // maximum chunk of compressed log text to send in a forward message  

#define STATTYPE_RESPONSE             0
#define STATTYPE_RESET                1
#define STATTYPE_REQUESTLINKSTATE     2
#define STATTYPE_REQUESTTREESTATE     3
#define STATTYPE_REQUESTJOINSTATE     4
#define STATTYPE_REQUESTROUTESTATS    5

typedef struct {                          // structure for sending tuples to join point, and from j.p. to Base
  uint8_t cmd;
  uint8_t cache_multicast;
  PAGE page;
} PACKING_MACRO TUPLE_MSGHI;

typedef struct {
  ADDRESS source_node, dest_node1, dest_node2, neighbor_node;
  uint8_t path_len;
  ADDRESS path[MAX_PATHLEN];
} PACKING_MACRO PATHCOLLAPSE_HINT;

typedef struct {                          // path collapse hint message
  uint8_t cmd;

  uint8_t hint_count;
  PATHCOLLAPSE_HINT hints[MAX_PATHCOLLAPSEHINTS];
} PACKING_MACRO PATHCOLLAPSE_MSGHI;

typedef struct {
  uint8_t cmd;

  uint8_t type;     // 0: response, 1: request for reset, 2-15: statistics requests
  
  ADDRESS dest_node;   // sent if type != response
  
  // Sent if type == response
  uint8_t fragment_count;
  uint8_t fragment_index;
  uint8_t stat_size;
  uint8_t stats[MAX_STATSIZE];   // ASCII text of log file determined by type
} PACKING_MACRO STATS_MSGHI;

typedef struct {                  // structure for caching multicast at split nodes
  uint8_t used;

  uint8_t query_id, rel_id;
  ADDRESS source_node;            // the multicast root
  uint8_t buffer_len, *buffer;
} PACKING_MACRO MULTICASTCACHE_ENTRY;

MULTICASTCACHE_ENTRY multicast_cache[MULTICASTCACHE_SIZE];

void init_mquerycomp();

void handle_tuplemsghi(ADDRESS source_node, ADDRESS dest_node, uint8_t path_nodecount,
  ADDRESS *path_nodes, uint8_t data_len, uint8_t *data);
void handlefail_tuplemsghi(ADDRESS source_node, ADDRESS dest_node, uint8_t path_nodecount,
  ADDRESS *path_nodes, uint8_t data_len, uint8_t *data);
void send_tuplemsg(TUPLE_MSGHI *msg);
void handle_pathcollapsemsghi(ADDRESS source_node, ADDRESS dest_node, uint8_t path_nodecount,
  ADDRESS *path_nodes, uint8_t data_len, uint8_t *data);
void handle_statsmsghi(ADDRESS source_node, ADDRESS dest_node, uint8_t path_nodecount,
  ADDRESS *path_nodes, uint8_t data_len, uint8_t *data);

void handleforwardinter_tuple(FORWARD_MSG *msg);
uint8_t handlesendmulticast_tuple(FORWARD_MSG *msg);
void clearmulticastpayload_tuple(uint8_t *data_len, uint8_t *data, ADDRESS source_node);
uint8_t merge_tuple(FORWARD_MSG *msg1, FORWARD_MSG *msg2);
uint8_t merge_pathcollapse(FORWARD_MSG *msg1, FORWARD_MSG *msg2);

uint8_t check_queriesrunning();
void timer_querycomp();
uint8_t query_percentremaining(uint8_t query_id);

uint8_t addtuple_wrap(PAGE *p, uint8_t tuple_len, ATTRIBUTE *tuple);
uint8_t gettuple_wrap(PAGE *p, uint8_t tuple_index, uint8_t *tuple_len, ATTRIBUTE *tuple);


